// EWFNET.cpp : Defines the initialization routines for the DLL.
//
//SJJ Embedded Micro Solutions
//Copyright (c) 2004 SJJ Micro Solutions    All Rights Reserved
//
//EWFNET DLL
//
// Date: 12/03/04 - Comments generated
//
//A modified version of the VB 6.0 solution developed by Dan Goldenberg who
//orignally used the EWFCMD code from a the article: "Controlling EWF by Using the EWF APIs" 
//by Sean Liming.
//
//This DLL performs the basic EWF function to Enable, Disable, Commit, CommitandDisableLive,
//Clear, and get status. Combined with EWFAPIC.DLL a .NET Class Library, C# and VB.NET
//applications can make EWF calls with a certain level of abstractions and without the
//details of access the drive handles.
//
//If you add new functions to this DLL, you need to add the export name to EWFNET.DEF
//and add the functions to the EWFAPIC .NET Class Library with P/Invoke call to the
//new function.
//
//If you want to rebuild the DLL, you will have to include the EWFAPI.H file and 
//change the linbrary path to the EWFAPI.LIB in the input linker 
//properties for this solution.

//Source code is provided as is without any warranty
//

#include "stdafx.h"
#include "EWFNET.h"
#include <windows.h>
#include <stdio.h>
#include "ewfapi.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

// CEWFNETApp

BEGIN_MESSAGE_MAP(CEWFNETApp, CWinApp)
END_MESSAGE_MAP()


// CEWFNETApp construction

CEWFNETApp::CEWFNETApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CEWFNETApp object

CEWFNETApp theApp;


// CEWFNETApp initialization

BOOL CEWFNETApp::InitInstance()
{
	CWinApp::InitInstance();

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
/*

EwfClearCommand

Routine description:

  This routine does EwfMgrClearCommand. 
  First, a handle is opened to a protected volume, then the 
  EwfMgrClearCommand function is called.

  EwfClearCommand:

    Command: Clears any pending commands 
             from the desired protected volume.

    Reboot:  Not required.

    Supported on EWF configurations of type EWF_DISK and 
    EWF_RAM.

Arguments:

  pszUsersDrive

    Volume name obtained from the calling program
    in the form C: 

Return value:

  ERROR_SUCCESS if success; otherwise, a Win32 error code.

--*/

DWORD _stdcall EwfClearCommand ( LPCTSTR pszUsersDrive ) 
{

	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);
  
	// Use the volume name to open a handle to this protected volume.
	hProVol = EwfMgrOpenProtected(szProVolName);

	if (hProVol == INVALID_HANDLE_VALUE) 
	{ 
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}
 
	//Perform the operation, return an error if failed.
	if (!EwfMgrClearCommand(hProVol))
	{
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}
	  
	EwfMgrClose(hProVol);
	return dwStatus;
  
}


/*++
EwfEnable

Routine description:

  This routine does EwfEnable. 
  First, a handle is opened to a protected volume, and then the 
  command is issued.

  EwfEnable:

    Command: Enables a currently disabled overlay on the specified volume
             by creating a new overlay at level 1 and setting the current 
             level to 1.

  Reboot:  Required - but if successful let the calling program take responsiblity for that.

    Supported on the EWF configuration types EWF_DISK, EWF_RAM, and 
    EWF_RAM_REG.

  Arguments:

			pszUsersDrive - Volume name obtained from the calling program  
			in the form C: 
    
Return value:

  ERROR_SUCCESS if success; otherwise, a Win32 error code.

--*/
 
DWORD EwfEnable ( LPCTSTR pszUsersDrive ) 
{

	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	BOOL bResult = FALSE;
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);

	// Use the volume name to open a handle to this protected volume.
	hProVol = EwfMgrOpenProtected(szProVolName);
	if (hProVol == INVALID_HANDLE_VALUE) 
	 { 
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	 }

	//Perform the operation, return an error if failed.
	bResult = EwfMgrEnable(hProVol);
	if (!bResult) 
	{
	 dwStatus = GetLastError();
	 EwfMgrClose(hProVol);
	 return dwStatus;
	}

	 EwfMgrClose(hProVol);
	 return dwStatus;

}


/*++
EwfDisable

Routine description:

  This routine does EwfDisable. First, a handle 
  is opened to a protected volume, and then the command is issued. 

  EwfDisable:

    Command: Disables a currently enabled overlay on the 
             specified volume.

  Reboot:  Required - Disable overlay or not
    Supported on the EWF configuration types EWF_DISK, EWF_RAM, and 
    EWF_RAM_REG (special - require the second argument to be true).
  
  Arguments:

			pszUsersDrive - Volume name obtained from the calling program  
			in the form C: 
		
			RamReg - Boolean value required for RamReg configurations
    
Return value:

  ERROR_SUCCESS if success; otherwise, a Win32 error code.

--*/

DWORD EwfDisable ( LPCTSTR pszUsersDrive, bool RamReg ) 
{

	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	BOOL bResult = FALSE;
	BOOL bRamReg = FALSE;	
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);

	// Use the volume name to open a handle to this protected volume.
	hProVol = EwfMgrOpenProtected(szProVolName);
	if (hProVol == INVALID_HANDLE_VALUE) 
	{ 
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}

	// For EWF_RAM_REG configurations, the second parameter (commit)
	// must be TRUE. This will commit the EWF_RAM_REG disable state,
	// which is required to disable the EWF_RAM_REG configuration.

	//bResult = EwfMgrDisable(hProVol,FALSE);

	if ( RamReg ) 
		{
			bRamReg = TRUE;
		}
	else
		{
			bRamReg = FALSE;
		}

	//Perform the operation, return an error if failed.
	bResult = EwfMgrDisable(hProVol,bRamReg);

	if (!bResult) 
	{
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}

	EwfMgrClose(hProVol);
	return dwStatus;

}

/*++
EwfCommit

Routine description:

  This routine does Ewf Commit. First, a handle 
  is opened to a protected volume, and then the command is issued. 

  EwfMgrCommit:

    Command: Commits all current level data in the overlay 
             to the protected volume, creating a new overlay at level 1 
             and setting the current level to 1.

    Reboot:  Required - but if successful let the calling program take 
			 responsiblity for that.

    Supported on the EWF configuration types EWF_DISK, EWF_RAM, and 
    EWF_RAM_REG.

  
	Arguments:

		pszUsersDrive -  Volume name obtained from the calling program
		in the form C: 
    
Return value:

  ERROR_SUCCESS if success; otherwise, a Win32 error code.

--*/


DWORD EwfCommit ( LPCTSTR pszUsersDrive ) 
{

	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	BOOL bResult = FALSE;
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);

	// Use the volume name to open a handle to this protected volume.
	hProVol = EwfMgrOpenProtected(szProVolName);
	if (hProVol == INVALID_HANDLE_VALUE) 
	{ 
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}

	//Perform the operation, return an error if failed.
	bResult = EwfMgrCommit(hProVol);
	if (!bResult) 
	{
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}

	EwfMgrClose(hProVol);
	return dwStatus;

}

/*++
EwfCommitandDisableLive

Routine description:

  This routine does EwfCommitandDisableLive. First, a handle 
  is opened to a protected volume, and then the command is issued. 

  EwfCommitandDisableLive

    Command: Commits all current RAM overlay data to the protected
	volume and disables EWF. No Reboot required

    Supported on the EWF configuration types EWF_RAM, and EWF_RAM_REG.

  
Arguments:

  pszUsersDrive - Volume name obtained from the calling program
  in the form C: 

    
Return value:

  ERROR_SUCCESS if success; otherwise, a Win32 error code.

--*/

DWORD EwfCommitandDisableLive ( LPCTSTR pszUsersDrive ) 
{

	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	BOOL bResult = FALSE;
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);

	// Use the volume name to open a handle to this protected volume.
	hProVol = EwfMgrOpenProtected(szProVolName);
	if (hProVol == INVALID_HANDLE_VALUE) 
	{ 
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}

	//Perform the operation, return an error if failed.
	bResult = EwfMgrCommitAndDisableLive(hProVol);
	if (!bResult) 
	{
		dwStatus = GetLastError();
		EwfMgrClose(hProVol);
		return dwStatus;
	}

    EwfMgrClose(hProVol);
	return dwStatus;

}


/*++
EWFStatus_Type

Routine description:

  This routine does EwfMgrGetProtectedVolumeConfig and returns
  The Type of overlay being used on the drive. First, a handle 
  is opened to a protected volume, and then the command is issued. 

  EWFStatus_Type

    Command: Returns Overlay Type for the drive
    Supported on the EWF configuration ALL types.
  
Arguments:

  pszUsersDrive - Volume name obtained from the calling program
  in the form C: 
    
Return value:

  EWF_DISK, EWF_RAM, EWF_RAMREG, or UNKOWN

--*/


LPCTSTR EWFStatus_Type(LPCTSTR pszUsersDrive)
{
	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	BOOL bResult =FALSE;
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];
	PEWF_VOLUME_CONFIG pVolConfig = NULL;
	LPCTSTR sResult;

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);

	//Next, Open the handle and return error if necessary.
	hProVol = EwfMgrOpenProtected(szProVolName);
		if (hProVol == INVALID_HANDLE_VALUE) 
	{ 
		
		EwfMgrClose(hProVol);
		sResult ="Error opening handle";
		return sResult;
	}


	//Perform the operation
	pVolConfig = EwfMgrGetProtectedVolumeConfig(hProVol);

	//Store the Type result in a string
	switch (pVolConfig->Type)
				{
					case EWF_DISK:		sResult = "EWF_DISK" ; break;
					case EWF_RAM:		sResult = "EWF_RAM" ; break;
					case EWF_RAM_REG:   sResult = "EWF_RAM_REG" ; break;
					default:
						sResult = "Unknown";
					break;
				}

	// Close Handle and Clear pVolConfig
	LocalFree(pVolConfig);
	pVolConfig = NULL;
	EwfMgrClose(szProVolName);
	
	//Return the Type
	return sResult;
}

/*++
EWFStatus_State

Routine description:

  This routine does EwfMgrGetProtectedVolumeConfig and returns
  the state of overlay for the the drive - Enable or Disable. First, a handle 
  is opened to a protected volume, and then the command is issued. 

  EWFStatus_State

    Command: Returns Overlay State for the drive
    Supported on the EWF configuration ALL types.
  
Arguments:

  pszUsersDrive - Volume name obtained from the calling program
  in the form C: 
    
Return value:

   EWF_ENALBED, EWF_DISABLED, or UNKOWN

--*/

LPCTSTR EWFStatus_State(LPCTSTR pszUsersDrive)
{
	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	BOOL bResult =FALSE;
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];
	PEWF_VOLUME_CONFIG pVolConfig = NULL;
	LPCTSTR sResult;

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);

	//Next, Open the handle and return error if necessary.
	hProVol = EwfMgrOpenProtected(szProVolName);
	if (hProVol == INVALID_HANDLE_VALUE) 
	{ 
		
		EwfMgrClose(hProVol);
		sResult ="Error opening handle";
		return sResult;
	}
	
	//Perform the operation
	pVolConfig = EwfMgrGetProtectedVolumeConfig(hProVol);

	//Store the State result in a string
	switch (pVolConfig->State)
				{
					case EWF_ENABLED:	sResult ="EWF_ENABLED"	;  break;
					case EWF_DISABLED:  sResult ="EWF_DISABLED"	; break;
					default:
						sResult = "Unknown";
					break;
				}

	// Close Handle and Clear pVolConfig
	LocalFree(pVolConfig);
	pVolConfig = NULL;
	EwfMgrClose(szProVolName);

	//Return the State
	return sResult;

}

/*++
EWFStatus_Command

Routine description:

  This routine does EwfMgrGetProtectedVolumeConfig and returns
  the current boot command for the the drive - Enable or Disable. First, a handle 
  is opened to a protected volume, and then the command is issued. 

  EWFStatus_Command

    Command: Returns boot command for the drive
    Supported on the EWF configuration ALL types.
  
Arguments:

  pszUsersDrive - Volume name obtained from the calling program
  in the form C: 
    
Return value:

   EWF_NOCMD, EWF_ENABLE, EWF_DISABLE, EWF_COMMIT, or ERROR

--*/


LPCTSTR EWFStatus_Command(LPCTSTR pszUsersDrive)
{
	DWORD dwStatus = ERROR_SUCCESS;
	HANDLE hProVol = INVALID_HANDLE_VALUE;
	BOOL bResult =FALSE;
	WCHAR szProVolName[256];
	WCHAR UsersDriveUniCode[256];
	PEWF_VOLUME_CONFIG pVolConfig = NULL;
	LPCTSTR sResult;

	//Change the drive string to wide format
	MultiByteToWideChar(CP_ACP, 0, pszUsersDrive, -1, UsersDriveUniCode, 256);	
	swprintf(szProVolName, L"\\\\.\\%s", UsersDriveUniCode);

	//Next, Open the handle and return error if necessary.
	hProVol = EwfMgrOpenProtected(szProVolName);
		if (hProVol == INVALID_HANDLE_VALUE) 
	{ 
		
		EwfMgrClose(hProVol);
		sResult ="Error opening handle";
		return sResult;
	}
	
	//Perform the operation
	pVolConfig = EwfMgrGetProtectedVolumeConfig(hProVol);

	//Store the State result in a string
	switch (pVolConfig->BootCommand.Command)
		{
			case EWF_NO_CMD:    sResult =  "EWF_NO_CMD"	;  break;
			case EWF_ENABLE:    sResult =  "EWF_ENABLE"	;  break;
			case EWF_DISABLE:   sResult =  "EWF_DISABLE";  break;
			case EWF_COMMIT:    sResult =  "EWF_COMMIT"	;  break;
			default:
				sResult = "Error";   
			break;
		}

	// Close Handle and Clear pVolConfig
	LocalFree(pVolConfig);
	pVolConfig = NULL;
	EwfMgrClose(szProVolName);

	//Return the State
	return sResult;

}
